<template>
  <div class="person-viewer">
    <!-- Search Section -->
    <div class="search-section">
      <div class="search-container">
        <input v-model="searchQuery" type="text" class="search-input" placeholder="搜索人物..." @keyup.enter="searchPerson">
        <button class="search-button" @click="searchPerson">
          搜索
        </button>
      </div>
    </div>

    <div class="content-container">
      <!-- Chart Section - 左边 -->
      <div class="chart-section" style="height: calc(100vh - 145px);" :class="{ 'fullscreen': isFullscreen }">
        <div class="chart-card">
          <h2 class="card-title">
            关系图谱
          </h2>
          <div class="chart-legend">
            <div class="legend-item">
              <span class="legend-color center-color" />
              <span>中心人物</span>
            </div>
            <div class="legend-item">
              <span class="legend-color person-color" />
              <span>人物关系</span>
            </div>
            <div class="legend-item">
              <span class="legend-color org-color" />
              <span>机构关系</span>
            </div>
          </div>
          <div class="chart-controls">
            <!-- <button class="control-button" @click="zoomIn">
              <span class="control-icon">+</span>
            </button>
            <button class="control-button" @click="zoomOut">
              <span class="control-icon">-</span>
            </button> -->
            <button class="control-button" @click="resetZoom">
              <span class="control-icon">↺</span>
            </button>
            <button class="control-button" @click="toggleFullscreen">
              <span class="control-icon">⛶</span>
            </button>
          </div>
          <div v-if="selectedPerson" ref="chartContainer" class="chart-container" />
          <div v-else class="chart-container empty-chart">
            <div class="empty-chart-content">
              <h3 class="empty-title">
                暂无关系图谱数据
              </h3>
              <p class="empty-desc">
                请在左侧搜索框中输入人物姓名并点击搜索按钮
              </p>
            </div>
          </div>
          <div v-if="chartError" class="chart-error">
            图表加载失败: {{ chartError }}
          </div>
        </div>
      </div>

      <!-- Person Information Section - 右边 -->
      <div v-show="!isFullscreen" class="info-section" style="height: calc(100vh - 145px);">
        <div class="info-card" style="height: 60%; overflow-y: auto; height: 60%;">
          <h2 class="card-title">
            个人信息
          </h2>
          <div v-if="selectedPerson" class="info-content">
            <div class="info-item">
              <span class="info-label">姓名:</span>
              <span class="info-value">{{ selectedPerson.name }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">性别:</span>
              <span class="info-value">{{ selectedPerson.gender }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">民族:</span>
              <span class="info-value">{{ selectedPerson.grade }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">年龄:</span>
              <span class="info-value">{{ selectedPerson.age }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">配偶:</span>
              <span class="info-value">{{ selectedPerson.spouse }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">机构:</span>
              <span class="info-value">{{ selectedPerson.organization }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">职务:</span>
              <span class="info-value">{{ selectedPerson.position }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">军衔:</span>
              <span class="info-value">{{ selectedPerson.military_rank }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">政治面貌:</span>
              <span class="info-value">{{ selectedPerson.political_status }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">婚姻状态:</span>
              <span class="info-value">{{ selectedPerson.marital_status }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">出生日期:</span>
              <span class="info-value">{{ selectedPerson.birth_date }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">入党时间:</span>
              <span class="info-value">{{ selectedPerson.party_join_date }}</span>
            </div>

            <div class="info-item">
              <span class="info-label">电话号码:</span>
              <span class="info-value">{{ selectedPerson.phone_number }}</span>
            </div>
          </div>
          <div v-else class="info-content empty-info">
            <div class="empty-info-content">
              <h3 class="empty-title">
                暂无个人信息
              </h3>
              <p class="empty-desc">
                搜索人物后将显示详细信息
              </p>
            </div>
          </div>
        </div>

        <!-- Events Section -->
        <div class="events-card" style="height: 40%; overflow-y: auto;">
          <h2 class="card-title">
            人物事件
          </h2>
          <div class="events-content">
            <div class="event-tabs">
              <div v-for="(tab, index) in eventTabs" :key="index"
                :class="['event-tab', { active: activeTab === tab.type }]" @click="activeTab = tab.type">
                {{ tab.name }}
              </div>
            </div>
            <div v-if="selectedPerson" class="event-list">
              <div v-for="(event, index) in filteredEvents" :key="index" class="event-item">
                <div class="event-date">
                  {{ event.date }}
                </div>
                <div class="event-content">
                  <div class="event-title">
                    {{ event.title }}
                  </div>
                  <div class="event-description">
                    {{ event.description }}
                  </div>
                </div>
              </div>
              <div v-if="filteredEvents.length === 0" class="no-events">
                暂无相关事件
              </div>
            </div>
            <div v-else class="event-list empty-events">
              <div class="empty-events-content">
                <h3 class="empty-title">
                  暂无事件数据
                </h3>
                <p class="empty-desc">
                  搜索人物后将显示相关事件
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

var option = null

export default {
  name: 'PersonViewer',
  data() {
    return {
      searchQuery: '',
      selectedPerson: null,
      activeTab: 'all',
      eventTabs: [
        { name: '全部', type: 'all' },
        { name: '军衔晋升', type: 'jxjs' },
        { name: '职位任免', type: 'zwrm' },
        { name: '奖惩事件', type: 'jcsj' },
        { name: '专业评级', type: 'zypj' }
      ],
      chart: null,
      chartError: null,
      echartsLoaded: false,
      // 颜色映射
      colorMap: {
        center: {
          main: '#1890FF',
          gradient: new Array(2) // 将在初始化时填充
        },
        person: {
          main: '#52C41A',
          gradient: new Array(2)
        },
        org: {
          main: '#FA8C16',
          gradient: new Array(2)
        }
      },
      zoomLevel: 1,
      isFullscreen: false
    }
  },
  computed: {
    filteredEvents() {
      if (!this.selectedPerson) return [];

      if (this.activeTab === 'all') {
        return this.selectedPerson.events;
      } else {
        return this.selectedPerson.events.filter(event => event.type === this.activeTab);
      }
    }
  },
  mounted() {
    // 在组件挂载后立即加载ECharts
    this.loadECharts();

    // 监听ESC键退出全屏
    document.addEventListener('keydown', this.handleKeyDown);

    // 添加窗口大小改变监听
    window.addEventListener('resize', this.resizeChart);
  },
  beforeDestroy() {
    // 清理图表实例
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }

    // 移除事件监听
    window.removeEventListener('resize', this.resizeChart);
    document.removeEventListener('keydown', this.handleKeyDown);
  },
  methods: {
    quickSearch(name) {
      this.searchQuery = name;
      this.searchPerson();
    },
    toggleFullscreen() {
      this.isFullscreen = !this.isFullscreen;

      // 在下一个渲染周期调整图表大小
      this.$nextTick(() => {
        if (this.chart) {
          // 给DOM结构一些时间来调整
          setTimeout(() => {
            // 强制重新计算图表容器尺寸
            const container = this.$refs.chartContainer;
            if (container) {
              // 全屏时设置一个固定的大高度，确保撑满屏幕
              if (this.isFullscreen) {
                container.style.height = `${window.innerHeight - 80}px`;
              } else {
                container.style.height = '';
              }
            }

            this.chart.resize();

            // 全屏后重置图表并等待一小段时间后再次调整
            if (this.isFullscreen) {
              this.resetZoom();

              // 延迟一段时间再次调整，确保图表完全展开
              setTimeout(() => {
                if (this.chart) {
                  this.chart.resize();

                  // 稍微调整一下缩放比例以触发完全重绘
                  const currentZoom = this.zoomLevel;
                  this.chart.setOption({
                    series: [{
                      zoom: currentZoom * 0.95
                    }]
                  });

                  setTimeout(() => {
                    this.chart.setOption({
                      series: [{
                        zoom: currentZoom
                      }]
                    });
                  }, 100);
                }
              }, 300);
            }
          }, 200);
        }
      });
    },
    handleKeyDown(e) {
      // 按ESC键退出全屏
      if (e.key === 'Escape' && this.isFullscreen) {
        this.isFullscreen = false;
        this.$nextTick(() => {
          if (this.chart) {
            // 给DOM结构一些时间来调整
            setTimeout(() => {
              // 恢复正常模式下的容器高度
              const container = this.$refs.chartContainer;
              if (container) {
                container.style.height = '';
              }

              this.chart.resize();
              this.resetZoom();

              // 延迟一段时间再次调整，确保图表完全适应新大小
              setTimeout(() => {
                if (this.chart) {
                  this.chart.resize();
                }
              }, 300);
            }, 200);
          }
        });
      }
    },
    loadECharts() {
      // 在Vue原型上已经有$echarts了，直接使用
      if (this.$echarts) {
        this.echartsLoaded = true;
        console.log('ECharts已通过Vue原型加载');
        return Promise.resolve();
      }

      console.error('Vue原型上未找到$echarts');
      return Promise.reject(new Error('Vue原型上未找到$echarts'));
    },
    searchPerson() {
      this.chartError = null;

      // 模拟API调用，实际应用中应该调用后端API
      if (this.searchQuery.trim() === '') {
        return;
      }

      // 模拟数据，实际应用中应该从API获取
      this.selectedPerson = {
        name: '王程杰',
        gender: '男',
        grade: '高级',
        age: 30,
        position: '技术主管',
        political_status: '中共党员',
        marital_status: '已婚',
        spouse: "李文静",
        organization: "中电光谷",
        birth_date: "1990-01-01",
        party_join_date: "2010-01-01",
        phone_number: "885812",
        military_rank: "中校",
        events: [
          {
            type: 'jxjs',
            date: '2023-01-15',
            title: '晋升',
            description: '从上尉晋升少校'
          },
          {
            type: 'zwrm',
            date: '2022-06-10',
            title: '任命',
            description: '任命王程杰为市人大财政经济委员会副主任委员、开发区委员会副主任委员'
          },
          {
            type: 'jcsj',
            date: '2022-03-22',
            title: '奖励',
            description: '奖励王程杰安徽省五一劳动奖章'
          },
          {
            type: 'jcsj',
            date: '2022-03-22',
            title: '惩处',
            description: '惩处王程杰记过处分,违反部队管理规定，擅自离岗外出，未履行请假手续；不遵守保密纪律，在非保密场所谈论涉密事项。'
          },
          {
            type: 'zypj',
            date: '2021-11-05',
            title: '评级',
            description: '自专业三级晋升至专业四级'
          }
        ],
        // 扩展关系数据，添加人物和机构
        relations: [
          // 人物关系
          {
            name: '李四',
            relation: '下属',
            value: 3,
            type: 'person',
            children: [
              { name: '张小明', relation: '团队成员', value: 2, type: 'person' },
              { name: '王小红', relation: '团队成员', value: 2, type: 'person' },
              { name: '刘小华', relation: '实习生', value: 1, type: 'person' }
            ]
          },
          {
            name: '王五',
            relation: '下属',
            value: 3,
            type: 'person',
            children: [
              { name: '赵小刚', relation: '团队成员', value: 2, type: 'person' },
              { name: '钱小强', relation: '团队成员', value: 2, type: 'person' }
            ]
          },
          {
            name: '赵六',
            relation: '同事',
            value: 2,
            type: 'person',
            children: [
              { name: '孙小梅', relation: '项目合作', value: 1, type: 'person' },
              { name: '周小伟', relation: '项目合作', value: 1, type: 'person' }
            ]
          },
          {
            name: '钱七',
            relation: '上级',
            value: 4,
            type: 'person',
            children: [
              { name: '吴小龙', relation: '部门同事', value: 2, type: 'person' },
              { name: '郑小虎', relation: '部门同事', value: 2, type: 'person' },
              { name: '冯小云', relation: '部门同事', value: 2, type: 'person' }
            ]
          },
          {
            name: '孙八',
            relation: '合作伙伴',
            value: 1,
            type: 'person',
            children: [
              { name: '陈小林', relation: '项目对接', value: 1, type: 'person' },
              { name: '杨小光', relation: '技术支持', value: 1, type: 'person' }
            ]
          },

          // 机构关系
          {
            name: '技术研发部',
            relation: '所属部门',
            value: 5,
            type: 'org',
            children: [
              { name: '前端团队', relation: '工作团队', value: 4, type: 'org' },
              { name: '后端团队', relation: '协作团队', value: 3, type: 'org' },
              { name: '测试团队', relation: '协作团队', value: 3, type: 'org' }
            ]
          },
          {
            name: '创新实验室',
            relation: '兼职部门',
            value: 2,
            type: 'org',
            children: [
              { name: '人工智能组', relation: '研究小组', value: 2, type: 'org' }
            ]
          },
          {
            name: '华东技术大学',
            relation: '毕业院校',
            value: 2,
            type: 'org',
            children: [
              { name: '计算机科学系', relation: '就读院系', value: 2, type: 'org' },
              { name: '校友会', relation: '成员单位', value: 1, type: 'org' }
            ]
          },
          {
            name: '行业标准委员会',
            relation: '外部组织',
            value: 1,
            type: 'org',
            children: [
              { name: '技术标准工作组', relation: '工作小组', value: 1, type: 'org' }
            ]
          }
        ]
      };

      // 直接使用this.$echarts，无需加载CDN资源
      this.$nextTick(() => {
        this.initChart();

        // 延迟执行一次重置，确保图表适应容器
        setTimeout(() => {
          this.resetZoom();
        }, 500);
      });
    },
    // 设置人物数据并初始化图表
    setPersonData() {
      // 模拟数据，实际应用中应该从API获取
      this.selectedPerson = {
        name: '王程杰',
        gender: '男',
        grade: '汉',
        political_status: '中共党员',
        marital_status: '已婚',
        spouse: "李文静",
        organization: "中电光谷",
        position: "技术主管",
        birth_date: "1990-01-01",
        party_join_date: "2010-01-01",
        phone_number: "885812",
        military_rank: "中校",
        events: [
          {
            type: 'task',
            date: '2023-01-15',
            title: '项目任务',
            description: '负责XX项目的架构设计和技术选型'
          },
          {
            type: 'promotion',
            date: '2022-06-10',
            title: '晋升',
            description: '从开发工程师晋升为技术主管'
          },
          {
            type: 'task',
            date: '2022-03-22',
            title: '技术攻关',
            description: '解决了系统性能瓶颈问题'
          },
          {
            type: 'discipline',
            date: '2021-11-05',
            title: '警告',
            description: '因代码质量问题收到口头警告'
          }
        ],
        // 扩展关系数据，添加人物和机构
        relations: [
          // 人物关系
          {
            name: '李四',
            relation: '下属',
            value: 3,
            type: 'person',
            children: [
              { name: '张小明', relation: '团队成员', value: 2, type: 'person' },
              { name: '王小红', relation: '团队成员', value: 2, type: 'person' },
              { name: '刘小华', relation: '实习生', value: 1, type: 'person' }
            ]
          },
          {
            name: '王五',
            relation: '下属',
            value: 3,
            type: 'person',
            children: [
              { name: '赵小刚', relation: '团队成员', value: 2, type: 'person' },
              { name: '钱小强', relation: '团队成员', value: 2, type: 'person' }
            ]
          },
          {
            name: '赵六',
            relation: '同事',
            value: 2,
            type: 'person',
            children: [
              { name: '孙小梅', relation: '项目合作', value: 1, type: 'person' },
              { name: '周小伟', relation: '项目合作', value: 1, type: 'person' }
            ]
          },
          {
            name: '钱七',
            relation: '上级',
            value: 4,
            type: 'person',
            children: [
              { name: '吴小龙', relation: '部门同事', value: 2, type: 'person' },
              { name: '郑小虎', relation: '部门同事', value: 2, type: 'person' },
              { name: '冯小云', relation: '部门同事', value: 2, type: 'person' }
            ]
          },
          {
            name: '孙八',
            relation: '合作伙伴',
            value: 1,
            type: 'person',
            children: [
              { name: '陈小林', relation: '项目对接', value: 1, type: 'person' },
              { name: '杨小光', relation: '技术支持', value: 1, type: 'person' }
            ]
          },

          // 机构关系
          {
            name: '技术研发部',
            relation: '所属部门',
            value: 5,
            type: 'org',
            children: [
              { name: '前端团队', relation: '工作团队', value: 4, type: 'org' },
              { name: '后端团队', relation: '协作团队', value: 3, type: 'org' },
              { name: '测试团队', relation: '协作团队', value: 3, type: 'org' }
            ]
          },
          {
            name: '创新实验室',
            relation: '兼职部门',
            value: 2,
            type: 'org',
            children: [
              { name: '人工智能组', relation: '研究小组', value: 2, type: 'org' }
            ]
          },
          {
            name: '华东技术大学',
            relation: '毕业院校',
            value: 2,
            type: 'org',
            children: [
              { name: '计算机科学系', relation: '就读院系', value: 2, type: 'org' },
              { name: '校友会', relation: '成员单位', value: 1, type: 'org' }
            ]
          },
          {
            name: '行业标准委员会',
            relation: '外部组织',
            value: 1,
            type: 'org',
            children: [
              { name: '技术标准工作组', relation: '工作小组', value: 1, type: 'org' }
            ]
          }
        ]
      };

      // 确保DOM已经更新后再初始化图表
      this.$nextTick(() => {
        // 给DOM一点时间渲染
        setTimeout(() => {
          try {
            this.initChart();
            console.log('图表初始化成功');
          } catch (err) {
            console.error('初始化图表失败:', err);
            this.chartError = '初始化图表失败: ' + err.message;
          }
        }, 100);
      });
    },
    // 预处理数据，直接在数据中添加颜色属性
    processChartData() {
      const centerName = this.selectedPerson.name;

      // 递归处理节点和边的数据
      const nodes = [];
      const edges = [];
      let nodeId = 0;

      const processNode = (node, parentId = null) => {
        const currentId = nodeId++;

        // 创建节点
        const newNode = {
          id: currentId,
          name: node.name,
          value: node.value,
          type: node.type,
          relation: node.relation,
          category: node.name === centerName ? 0 : node.type === 'org' ? 1 : 2,
          symbolSize: node.name === centerName ? 35 : 25,
          itemStyle: {
            color: node.name === centerName ? '#fac455' :
              node.type === 'org' ? '#7ec2f3' : '#91d5ff',
            borderColor: node.name === centerName ? '#fac455' :
              node.type === 'org' ? '#7ec2f3' : '#91d5ff',
            borderWidth: 1,
            shadowColor: 'rgba(0, 0, 0, 0.1)',
            shadowBlur: 2
          },
          label: {
            show: true,
            position: 'right',
            distance: 5,
            fontSize: 12,
            color: '#333',
            backgroundColor: 'rgba(255, 255, 255, 0.9)',
            padding: [4, 8],
            borderRadius: 2
          }
        };

        nodes.push(newNode);

        // 如果有父节点，创建边
        if (parentId !== null) {
          edges.push({
            source: parentId,
            target: currentId,
            lineStyle: {
              color: '#ccc',
              width: 1
            }
          });
        }

        // 处理子节点
        if (node.children && node.children.length > 0) {
          node.children.forEach(child => {
            processNode(child, currentId);
          });
        }

        return currentId;
      };

      // 创建根节点
      const rootNode = {
        name: centerName,
        value: 10,
        type: 'person',
        children: []
      };

      // 添加关系节点
      if (this.selectedPerson.relations && this.selectedPerson.relations.length > 0) {
        rootNode.children = this.selectedPerson.relations;
      }

      // 处理关系数据结构
      processNode(rootNode);

      // 添加"个人属性"节点
      const personalAttrNodeId = nodeId++;
      nodes.push({
        id: personalAttrNodeId,
        name: "个人属性",
        symbolSize: 30,
        category: 3,
        itemStyle: {
          color: '#1890ff',
          borderColor: '#1890ff',
          borderWidth: 1,
          shadowColor: 'rgba(0, 0, 0, 0.2)',
          shadowBlur: 5
        },
        label: {
          show: true,
          position: 'inside',
          fontSize: 12,
          color: '#fff'
        }
      });

      // 连接中心节点和个人属性节点
      edges.push({
        source: 0,
        target: personalAttrNodeId,
        lineStyle: {
          color: '#1890ff',
          width: 1,
          curveness: 0
        }
      });

      // 添加个人属性
      const attributes = [
        { key: '性别', value: this.selectedPerson.gender },
        { key: '民族', value: this.selectedPerson.grade },
        { key: '年龄', value: this.selectedPerson.age },
        { key: '配偶', value: this.selectedPerson.spouse },
        { key: '机构', value: this.selectedPerson.organization },
        { key: '职务', value: this.selectedPerson.position },
        { key: '军衔', value: this.selectedPerson.military_rank },
        { key: '政治面貌', value: this.selectedPerson.political_status },
        { key: '婚姻状态', value: this.selectedPerson.marital_status },
        { key: '出生日期', value: this.selectedPerson.birth_date },
        { key: '入党时间', value: this.selectedPerson.party_join_date },
        { key: '电话号码', value: this.selectedPerson.phone_number }
      ];

      // 添加属性节点
      attributes.forEach((attr, index) => {
        if (attr.value) {
          const attrNodeId = nodeId++;
          nodes.push({
            id: attrNodeId,
            name: `${attr.key}: ${attr.value}`,
            category: 4,
            symbolSize: 25,
            itemStyle: {
              color: '#fff',
              borderColor: '#1890ff',
              borderWidth: 1
            },
            label: {
              show: true,
              position: 'right',
              fontSize: 12,
              color: '#333'
            }
          });

          // 连接到个人属性节点
          edges.push({
            source: personalAttrNodeId,
            target: attrNodeId,
            lineStyle: {
              color: '#1890ff',
              width: 1,
              curveness: 0.1
            }
          });
        }
      });

      return { nodes, edges };
    },
    initChart() {
      if (!this.selectedPerson || !this.$refs.chartContainer) {
        return;
      }

      if (this.chart) {
        this.chart.dispose();
      }

      const container = this.$refs.chartContainer;
      if (container.offsetHeight < 200) {
        container.style.height = '600px';
      }
      if (container.offsetWidth < 100) {
        container.style.width = '100%';
      }

      this.chart = this.$echarts.init(container);
      const { nodes, edges } = this.processChartData();

      const option = {
        backgroundColor: '#ffffff',
        tooltip: {
          trigger: 'item',
          formatter: params => {
            const data = params.data;
            if (!data) return '';
            return data.name;
          }
        },
        series: [{
          type: 'graph',
          layout: 'force',
          force: {
            repulsion: 300,
            gravity: 0.1,
            edgeLength: 100,
            layoutAnimation: true
          },
          roam: true,
          label: {
            show: true,
            position: 'right',
            formatter: '{b}'
          },
          data: nodes,
          links: edges,
          categories: [
            { name: '中心人物' },
            { name: '机构' },
            { name: '人物' },
            { name: '属性分类' },
            { name: '具体属性' }
          ],
          lineStyle: {
            opacity: 0.9,
            width: 1.5,
            curveness: 0
          }
        }]
      };

      this.chart.setOption(option);
    },

    // 创建背景图案
    createPatternImage() {
      const canvas = document.createElement('canvas');
      canvas.width = 20;
      canvas.height = 20;
      const ctx = canvas.getContext('2d');

      // 填充白色背景
      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, 20, 20);

      // 绘制点状图案
      ctx.fillStyle = 'rgba(0, 0, 0, 0.02)';
      ctx.beginPath();
      ctx.arc(10, 10, 0.8, 0, Math.PI * 2);
      ctx.fill();

      return canvas.toDataURL();
    },
    // 缩放控制
    zoomIn() {
      if (!this.chart) return;

      this.zoomLevel *= 1.2;
      this.chart.setOption({
        series: [{
          zoom: this.zoomLevel
        }]
      });
    },
    zoomOut() {
      if (!this.chart) return;

      console.log(option)

      this.zoomLevel /= 1.2;
      this.chart.setOption(option);
    },
    resetZoom() {
      if (!this.chart) return;

      this.zoomLevel = 1;

      // 先调整图表大小以适应容器
      this.chart.resize();

      // 短暂延迟后强制更新图表
      setTimeout(() => {
        // 先将缩放设为稍小值，触发完整重绘
        this.chart.setOption({
          series: [{
            zoom: 0.9
          }]
        });

        // 然后设置为标准大小
        setTimeout(() => {
          this.chart.setOption({
            series: [{
              zoom: 1
            }]
          });
        }, 100);
      }, 50);
    },
    resizeChart() {
      if (this.chart) {
        this.chart.resize();
        // 如果图表已经初始化，延迟调整一次缩放
        setTimeout(() => {
          // 轻微调整缩放以触发重绘
          this.chart.setOption({
            series: [{
              zoom: this.zoomLevel * 0.99
            }]
          });
          // 然后恢复正常缩放
          setTimeout(() => {
            this.chart.setOption({
              series: [{
                zoom: this.zoomLevel
              }]
            });
          }, 50);
        }, 150);
      }
    }
  }
}
</script>

<style scoped>
.person-viewer {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  background-color: #f0f2f5;
  font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
  color: #2c3e50;
  overflow: hidden;
}

.search-section {
  padding: 12px 20px;
  background-color: white;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  flex: 0 0 auto;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 10;
  position: relative;
}

.search-container {
  display: flex;
  max-width: 500px;
  margin: 0 auto 0 0;
  padding-left: 20px;
}

.search-input {
  flex: 1;
  padding: 12px 16px;
  border: 1px solid #e4e7ed;
  border-radius: 8px 0 0 8px;
  font-size: 14px;
  outline: none;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
  background-color: #f5f7fa;
  color: #606266;
}

.search-input:focus {
  border-color: #409eff;
  background-color: #fff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2),
    inset 0 1px 3px rgba(0, 0, 0, 0.05);
}

.search-button {
  padding: 12px 24px;
  background: linear-gradient(135deg, #409eff, #146ce0);
  color: white;
  border: none;
  border-radius: 0 8px 8px 0;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
}

.search-button:hover {
  background: linear-gradient(135deg, #66b1ff, #3a8ee6);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
  transform: translateY(-1px);
}

.content-container {
  display: flex;
  flex-direction: column;
  padding: 20px;
  gap: 20px;
  flex: 1;
  height: calc(100vh - 165px); /* 减去搜索栏的高度 */
  overflow: hidden;
}

@media (min-width: 1024px) {
  .content-container {
    flex-direction: row;
    align-items: stretch;
    height: calc(100vh - 165px);
  }

  .chart-section {
    width: 70%;
    height: 100%;
  }

  .info-section {
    width: 30%;
    height: 100%;
  }
}

.chart-section {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.info-section {
  display: flex;
  flex-direction: column;
  gap: 20px;
  height: 100%;
}

.info-card,
.events-card,
.chart-card {
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1px solid rgba(0, 0, 0, 0.03);
}

.info-card:hover,
.events-card:hover,
.chart-card:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  transform: translateY(-2px);
  border-color: rgba(64, 158, 255, 0.1);
}

.info-content {
  padding: 20px;
  overflow-y: auto;
  scrollbar-width: thin;
  flex: 1;
}

.info-content::-webkit-scrollbar,
.event-list::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.info-content::-webkit-scrollbar-track,
.event-list::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.info-content::-webkit-scrollbar-thumb,
.event-list::-webkit-scrollbar-thumb {
  background: #dcdfe6;
  border-radius: 3px;
  transition: all 0.2s;
}

.info-content::-webkit-scrollbar-thumb:hover,
.event-list::-webkit-scrollbar-thumb:hover {
  background: #c0c4cc;
}

.chart-container {
  flex: 1;
  padding: 10px;
  width: 100%;
  min-height: 500px;
  height: calc(100% - 110px) !important; /* 调整非全屏时的高度 */
  background-color: #ffffff;
  border-radius: 0 0 12px 12px;
  position: relative;
  overflow: hidden;
}

.card-title {
  margin: 0;
  padding: 16px 20px;
  font-size: 16px;
  font-weight: 600;
  border-bottom: 1px solid #ebeef5;
  color: #2c3e50;
  background: linear-gradient(to right, #fafafa, #f5f7fa);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  letter-spacing: 0.5px;
}

.chart-legend {
  display: flex;
  padding: 12px 20px;
  gap: 24px;
  border-bottom: 1px solid #ebeef5;
  background: linear-gradient(to right, #fafafa, #f5f7fa);
  flex-wrap: wrap;
}

.legend-item {
  display: flex;
  align-items: center;
  font-size: 13px;
  color: #606266;
  padding: 4px 8px;
  border-radius: 4px;
  transition: all 0.2s;
}

.legend-item:hover {
  background-color: rgba(64, 158, 255, 0.1);
}

.legend-color {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 8px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.center-color {
  background: linear-gradient(135deg, #1890ff, #36cbcb);
}

.person-color {
  background: linear-gradient(135deg, #52c41a, #b7eb8f);
}

.org-color {
  background: linear-gradient(135deg, #fa8c16, #ffd591);
}

.chart-controls {
  display: flex;
  flex-direction: column;
  position: absolute;
  bottom: 30px;
  right: 30px;
  gap: 8px;
  z-index: 200;
  background-color: rgba(255, 255, 255, 0.75);
  padding: 8px;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(5px);
  border: 1px solid rgba(255, 255, 255, 0.6);
  transition: all 0.25s ease;
}

.chart-controls:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.control-button {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid rgba(200, 200, 200, 0.3);
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  color: #666;
  font-weight: normal;
}

.control-button::before {
  content: none; /* 移除之前的光泽效果 */
}

.control-icon {
  font-size: 16px;
  transition: transform 0.2s ease;
}

.control-button:hover {
  transform: translateY(-2px);
  background-color: #f8f8f8;
  box-shadow: 0 3px 7px rgba(0, 0, 0, 0.08);
}

.control-button:active {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.control-button:hover .control-icon {
  transform: scale(1.15);
}

/* 特定按钮样式 - 使用更柔和的颜色 */
.control-button:nth-child(1) {
  /* 放大按钮 */
  color: #6cc067;
}

.control-button:nth-child(2) {
  /* 缩小按钮 */
  color: #e77471;
}

.control-button:nth-child(3) {
  /* 重置按钮 */
  color: #e4a663;
}

.control-button:nth-child(4) {
  /* 全屏按钮 */
  color: #69a9e0;
}

/* 全屏模式下的控制按钮 */
.chart-section.fullscreen .chart-controls {
  bottom: 40px;
  right: 40px;
  background-color: rgba(255, 255, 255, 0.8);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

.info-item {
  display: flex;
  margin-bottom: 16px;
  padding: 8px 12px;
  border-bottom: 1px dashed #f0f0f0;
  transition: all 0.2s ease; /* 缩短过渡时间 */
  border-radius: 2px; /* 减小圆角 */
}

.info-item:hover {
  background-color: rgba(64, 158, 255, 0.08); /* 稍微调整背景色透明度 */
  padding: 8px 12px 8px 16px; /* 减小左侧padding的变化幅度 */
  border-bottom-color: rgba(64, 158, 255, 0.15);
}

.info-label {
  min-width: 80px;
  color: #606266;
  font-weight: 500;
}

.info-value {
  color: #303133;
  flex: 1;
  font-weight: 500;
}

.events-content {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.event-tabs {
  display: flex;
  border-bottom: 1px solid #ebeef5;
  background-color: #fafafa;
  flex-shrink: 0;
}

.event-tab {
  padding: 12px 16px;
  cursor: pointer;
  color: #606266;
  font-size: 14px;
  transition: all 0.3s;
  position: relative;
  opacity: 0.8;
}

.event-tab:hover {
  color: #409eff;
  background-color: rgba(64, 158, 255, 0.05);
  opacity: 1;
}

.event-tab.active {
  color: #409eff;
  font-weight: 500;
  opacity: 1;
}

.event-tab.active::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 30px;
  height: 2px;
  background-color: #409eff;
  border-radius: 1px;
  box-shadow: 0 1px 4px rgba(64, 158, 255, 0.3);
}

.event-list {
  padding: 12px 20px;
  flex: 1;
  overflow-y: auto;
  min-height: 50px;
}

.event-item {
  display: flex;
  padding: 12px 10px;
  border-bottom: 1px solid #f5f5f5;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 6px;
  margin-bottom: 8px;
}

.event-item:hover {
  background-color: #f9f9f9;
  transform: translateX(5px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.event-item:last-child {
  border-bottom: none;
}

.event-date {
  min-width: 100px;
  color: #909399;
  font-size: 13px;
  font-weight: 500;
  padding-right: 10px;
  border-right: 2px solid #ebeef5;
  display: flex;
  align-items: center;
}

.event-content {
  margin-left: 10px;
  flex: 1;
}

.event-title {
  font-weight: 600;
  margin-bottom: 6px;
  color: #303133;
  transition: color 0.2s;
}

.event-item:hover .event-title {
  color: #409eff;
}

.event-description {
  color: #606266;
  font-size: 13px;
  line-height: 1.5;
  margin-top: 4px;
}

.no-events {
  text-align: center;
  color: #909399;
  padding: 30px 0;
  font-size: 14px;
}

.chart-error {
  text-align: center;
  color: #f56c6c;
  padding: 20px;
  font-size: 14px;
  background-color: #fef0f0;
  border-radius: 4px;
  margin: 20px;
}

/* 空状态样式 */
.empty-chart {
  display: flex;
  justify-content: center;
  align-items: center;
}

.empty-chart-content,
.empty-info-content,
.empty-events-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  text-align: center;
}

.empty-title {
  font-size: 18px;
  color: #5e6d82;
  margin-bottom: 8px;
  font-weight: 500;
}

.empty-desc {
  font-size: 14px;
  color: #909399;
  margin-bottom: 24px;
  line-height: 1.6;
}

.sample-search {
  margin-top: 20px;
  text-align: center;
}

.sample-tags {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 10px;
}

.sample-tag {
  display: inline-block;
  padding: 6px 12px;
  background-color: #f0f2f5;
  color: #606266;
  border-radius: 4px;
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s;
}

.sample-tag:hover {
  background-color: #e6f7ff;
  color: #409eff;
}

.empty-info,
.empty-events {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

.event-tabs {
  flex-shrink: 0; /* 防止tabs被压缩 */
}

.card-title {
  flex-shrink: 0; /* 防止标题被压缩 */
}

/* 全屏模式样式 */
.chart-section.fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100vh !important;
  z-index: 1000;
  padding: 0;
  background-color: #f5f7fa;
}

.chart-section.fullscreen .chart-container {
  height: calc(100vh - 110px) !important; /* 调整高度，减去标题和图例的高度 */
  position: relative;
  padding: 20px 40px 20px 240px;
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-section.fullscreen .chart-card {
  height: 100vh;
  border-radius: 0;
  box-shadow: none;
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  padding: 0;
}

.chart-section.fullscreen .card-title {
  padding: 15px 15px 15px 240px;
  height: 50px; /* 固定标题高度 */
}

.chart-section.fullscreen .chart-legend {
  padding: 10px 15px 10px 240px;
  height: 60px; /* 固定图例高度 */
}

/* 全屏模式下修改图表控制按钮位置 */
.chart-section.fullscreen .chart-controls {
  bottom: 40px;
  right: 40px;
  background-color: rgba(255, 255, 255, 0.8);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  z-index: 1010;
}

.chart-card {
  display: flex;
  flex-direction: column;
  height: 100% !important; /* 确保卡片占满容器高度 */
  position: relative;
}
</style>